package com.vogue.supplymall.account.controller;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.google.gson.Gson;
import com.vogue.ssm.exception.UnknowException;
import com.vogue.supplymall.account.domain.dto.LoginUserInfo;
import com.vogue.supplymall.account.domain.model.User;
import com.vogue.supplymall.account.domain.service.UserService;
import com.vogue.supplymall.account.domain.service.impl.SpringContextUtils;
import com.vogue.supplymall.account.shiro.bean.TokenBean;
import com.vogue.supplymall.account.shiro.realm.AuthRealm;
import com.vogue.supplymall.account.shiro.token.MallUsernamePasswordToken;
import com.vogue.supplymall.common.domain.dto.StoreInfo;
import com.vogue.supplymall.common.domain.dto.UserInfo;
import com.vogue.supplymall.common.domain.tool.CodeProcessUtils;
import com.vogue.supplymall.common.domain.validate.Regex;
import com.vogue.supplymall.common.exception.IncorrectCredentialsException;


/**
 * Created by 崔岳 on 2017-11-30. <br>
 * 用户登录
 */
@Validated
@RestController
public class LoginController extends BaseController {

    public static final Logger LOGGER_LOGINCONTROLLER = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    private UserService userService;

//@RequiresRoles("admin")
    /**
    * 登录接口
    * @param appver 版本号
    * @param request 请求对象
    * @return ResponseEntity<Map<String, String>>
    * @throws Exception 登录异常
    */
    @RequestMapping("/ns/{appver}/account/login")
    public ResponseEntity<Map<String, String>> login(
            @PathVariable("appver") @Regex(name = "appver", regexcontent = "vernum")String appver,
            HttpServletRequest request) throws Exception {
        String username = null;
        String password = null;
        String loginInfo = null;
//(String)request.getAttribute(com.vogue.supplymall.account.domain.bean.ConstantBean.REQ_LOGIN_INFO_KEY);
        if (loginInfo == null) {
            username = request.getParameter("username");
            password = request.getParameter("password");
            if (username == null) {
                BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream(), "utf-8"));
                StringBuffer sb = new StringBuffer("");
                String temp;
                String params = null;
                try {
                    while ((temp = br.readLine()) != null) {
                        sb.append(temp);
                    }
                    params = sb.toString();
                } finally {
                    if (br != null) {
                        br.close();
                    }
                }
                Gson json = new Gson();
                TokenBean bean = json.fromJson(params, TokenBean.class);
                username = bean.getUsername();
                password = bean.getPassword();
                if (StringUtils.isEmpty(bean.getUsername())) {
                    if (bean.getLogininfo() != null) {
                        loginInfo = new String(CodeProcessUtils.decode(bean.getLogininfo()));
                        TokenBean loginBean = json.fromJson(loginInfo, TokenBean.class);
                        username = loginBean.getUsername();
                        password = loginBean.getPassword();
                    }
                }
            }
        }

        if (!SecurityUtils.getSubject().isAuthenticated()) {
            try {
                MallUsernamePasswordToken token = new MallUsernamePasswordToken(username, password);
                Subject subject = SecurityUtils.getSubject();
                subject.login(token);
            } catch (Exception ex) {
                LOGGER_LOGINCONTROLLER.error("authrealm identity login error : " + ex.toString());
                if (ex instanceof org.apache.shiro.authc.UnknownAccountException) {
                    throw new com.vogue.supplymall.common.exception.IncorrectCredentialsException();
                } else if (ex instanceof org.apache.shiro.authc.IncorrectCredentialsException) {
                    throw new com.vogue.supplymall.common.exception.IncorrectCredentialsException();
                } else if (ex instanceof org.apache.shiro.authc.ExcessiveAttemptsException) {
                    throw new com.vogue.supplymall.common.exception.ExcessiveAttemptsException(username);
                } else if (ex instanceof org.apache.shiro.authc.LockedAccountException) {
                    throw new com.vogue.supplymall.common.exception.LockedAccountException(username);
                } else if (ex instanceof com.vogue.supplymall.account.exception.MissLoginOrganShiroException) {
                    throw new com.vogue.supplymall.account.exception.MissLoginOrganException();
                } else {
                    throw new UnknowException("Find msg in log");
                }
            }
        }
        loginInfo = CodeProcessUtils.encode(("{\"username\":\"" + username + "\",\"password\":\"" + password + "\"}").getBytes());
        Map<String, String> map = new HashMap<String, String>();
        map.put("loginInfo", loginInfo);
        return new ResponseEntity<Map<String, String>>(map, HttpStatus.OK);
    }

    /**
     * 账户首页
     * @param request 请求对象
     * @param map 参数
     * @return ResponseEntity<String>
     * @throws Exception 异常
     */
    @RequestMapping("/is/account/home")
    public ResponseEntity<String> home(HttpServletRequest request, Map<String, Object> map) throws Exception {
        return new ResponseEntity<String>("home", HttpStatus.OK);
    }

    /**
     * 用户退出
     * @param appver 版本号
     * @param request 请求对象
     * @return ResponseEntity<Map<String, String>>
     * @throws Exception 异常
     */
    @RequestMapping("/ns/{appver}/account/logout")
    public ResponseEntity<Map<String, String>> logout(
            @PathVariable("appver") @Regex(name = "appver", regexcontent = "vernum")String appver,
            HttpServletRequest request) throws Exception {
        if (SecurityUtils.getSubject() != null && SecurityUtils.getSubject().isAuthenticated()) {
            UserInfo info = (UserInfo) SecurityUtils.getSubject().getPrincipal();
            AuthRealm authRealm = (AuthRealm) SpringContextUtils.getBeanByClass(AuthRealm.class);
            if (authRealm != null) {
                authRealm.clearAllCache(new SimplePrincipalCollection(AuthRealm.getCacheKey(info.getTel()), authRealm.getName()));
            }
            SecurityUtils.getSubject().logout();
        }
        Map<String, String> map = new HashMap<String, String>();
        map.put("info", "logout");
        return new ResponseEntity<Map<String, String>>(map, HttpStatus.OK);
    }

    /**
     * 获取登录用户的信息
     * @param appver 版本号
     * @param request 请求对象
     * @return ResponseEntity<LoginUserInfo>
     * @throws Exception 获取信息异常
     */
    @RequestMapping("/ns/{appver}/account/loginUserInfo")
    public ResponseEntity<LoginUserInfo> loginUserInfo(
            @PathVariable("appver") @Regex(name = "appver", regexcontent = "vernum")String appver,
            HttpServletRequest request) throws Exception {
        LoginUserInfo info = new LoginUserInfo();
        if (SecurityUtils.getSubject() != null && SecurityUtils.getSubject().isAuthenticated()) {
            UserInfo user = (UserInfo) SecurityUtils.getSubject().getPrincipal();
            User u = userService.get(user.getLoginId());
            if (user.getName() != null) {
                info.setName(user.getName());
            }
            if (user.getTel() != null) {
                info.setTel(user.getTel());
            }
            if (user.getHeadImgUrl() != null) {
                info.setHeadImgUrl(u.getHeadimgurl());
            } else {
                info.setHeadImgUrl("");
            }
            if (user.getEntName() != null) {
                info.setEntName(user.getEntName());
            }
            if (user.getSyscode() != null) {
                info.setSyscode(user.getSyscode().toString());
            }
            info.setLoginUserType(user.getLoginUserType());
            if (user.getOrganInfo() != null) {
                info.setOrgName(user.getOrganInfo().getName());
                if (user.getOrganInfo().getShopInfo() != null) {
                    info.setShopName(user.getOrganInfo().getShopInfo().getName());
                }
            }
            info.setSelOrgFlag(user.getSelOrgFlag());
            info.setIsAdmin(user.isAdmin());
//LOGGER.debug("登录人：" + user.getLoginId());
        } else {
            throw new IncorrectCredentialsException();
        }
        return new ResponseEntity<LoginUserInfo>(info, HttpStatus.OK);
    }

    /**
     * 获取当前登录人可管辖的仓库（需要根据切换的门店来查找）
     * @param appver 版本号
     * @return ResponseEntity<List<Map<String,String>>>
     * @throws Exception 异常
     */
    @RequestMapping(value = "/is/{appver}/account/loginUserShopStore", method = RequestMethod.POST)
    public ResponseEntity<List<Map<String, String>>> loginUserShopStore(
            @PathVariable("appver") @Regex(name = "appver", regexcontent = "vernum")String appver) throws Exception {
        List<Map<String, String>> storelist = new ArrayList<>();
        UserInfo user = (UserInfo) SecurityUtils.getSubject().getPrincipal();
        Map<String, String> infomap = null;
        if (user.getOrganInfo() != null && user.getOrganInfo().getStoreList() != null) {
            List<StoreInfo> slist = user.getOrganInfo().getStoreList();
            for (StoreInfo s : slist) {
                infomap = new HashMap<String, String>();
                infomap.put("id", String.valueOf(s.getId()));
                infomap.put("name", s.getName());
                infomap.put("matchid", s.getMatchid());
                storelist.add(infomap);
            }
        }
        return new ResponseEntity<List<Map<String, String>>>(storelist, HttpStatus.OK);
    }
}
